﻿using System;
using System.Collections.Generic;
using System.Linq;
using CoreLibrary;
using CoreLibrary.Paging;
using Entities.DataBase;
using Entities.DataBase.Obj;
using Entities.DataBase.Persistent;
using Entities.Enumeration;
using Modules.Tracking;
using WebService.Service.Transfer;

namespace WebService.Service {

    public class PackageServiceX : AbstractService, IPackageServiceX {

        public bool AddPackage(string passport, AddPackageRequest request) {
            return Run(passport, token => {
                Locate<IPackageRepository>().InsertAll(request.PackageItems.Select(item => new Package {
                    Id              = GuidUtil.GuidN(),
                    DateCreated     = item.DateCreated ?? DateTime.UtcNow,
                    CourierId       = item.CourierId,
                    Type            = item.Type,
                    TrackingId      = Util.GetString(item.TrackingId),
                    Description     = Util.GetString(item.Description),
                    Recipient       = Util.GetString(item.Recipient),
                    Reference       = Util.GetString(item.Reference),
                    PhoneNumber     = Util.GetString(item.PhoneNumber),
                    ShippingAddress = Util.GetString(item.ShippingAddress),
                    Status          = string.IsNullOrEmpty(item.TrackingId) ? PackageStatus.PENDING : PackageStatus.SHIPPING,
                }));
                return true;
            });
        }

        public bool UpdatePackage(string passport, UpdatePackageRequest request) {
            return Run(passport, token => {
                Locate<IPackageRepository>().Update(request.PackageId, new PackageUpdator {
                    CourierId       = request.CourierId,
                    Type            = request.Type,
                    DateCreated     = request.DateCreated,
                    Reference       = Util.GetString(request.Reference),
                    TrackingId      = Util.GetString(request.TrackingId),
                    Description     = Util.GetString(request.Description),
                    PhoneNumber     = Util.GetString(request.PhoneNumber),
                    Recipient       = Util.GetString(request.Recipient),
                    ShippingAddress = Util.GetString(request.ShippingAddress)
                });
                return true;
            });
        }

        public bool UpdatePackageStatus(string passport, string packageId, int status) {
            return Run(passport, token => {
                Locate<IPackageRepository>().UpdateStatus(packageId,status);
                return true;
            });
        }

        public bool UpdatePackageData(string passport, string packageId, string data) {
            return Run(passport, token => {
                Locate<IPackageRepository>().UpdateData(packageId, Util.GetString(data));
                return true;
            });
        }


        public bool RemovePackage(string passport, string packageId) {
            return Run(passport, token => {
                var pack = Locate<IPackageRepository>().Get(packageId);
                if (!string.IsNullOrEmpty(pack.Reference)) {
                     throw new ArgumentException("当前包裹为库存或者订单包裹，不能删除");
                }

                Locate<IPackageRepository>().Remove(packageId);
                return true;
            });
        }

        public bool RemovePackages(string passport, string reference) {
            return Run(passport, token => {
                Locate<IPackageRepository>().RemoveByReference(Util.GetString(reference));
                return true;
            });
        }

        public string TrackPackage(string passport, string packageId) {
            return Run(passport, token => {
                var package   = Services.Locate<IPackageRepository>().Get(packageId);
                var result    = Services.Locate<IShipmentService>().Track(new TrackRequest {
                    TrackId   = package.TrackingId,
                    CourierId = package.CourierId,
                    DateTrack = DateTime.UtcNow
                });

                if (result.Succeed) {
                    UpdatePackageData(passport, packageId, result.Data);
                }

                return result.Succeed ? result.Data 
                                      : "查询失败";
            });
        }

        public PagingResult<PackageInfo> ListPackages(string passport, PagingRequest request) {
            return Run(passport, token => {
                var packages = Services.Locate<IPackageRepository>().ListByKeywords(Util.GetString(request.Keyword));
                return new PagingResult<PackageInfo> {
                    Offset = request.Offset,
                    Total  = packages.Count,
                    Data   = packages.Skip(request.Offset).Take(request.Limit).ToList()
                };
            });
        }

        public List<PackageInfo> ListPackagesByReference(string passport, string referenceId) {
            return Run(passport, token => Services.Locate<IPackageRepository>()
                                                  .ListByReference(Util.GetString(referenceId)));
        }

        public PagingResult<PackageInfo> SearchPackages(string passport, SearchPackageRequest request) {
            return Run(passport, token => {
                var packages = Locate<IPackageRepository>()
                              .SearchPackages(request.CourierId, 
                                              request.Type, 
                                              Util.GetString(request.CustomerName), 
                                              Util.GetString(request.TrackingId)
                );

                return new PagingResult<PackageInfo> {
                    Offset = request.Offset,
                    Total  = packages.Count,
                    Data   = packages.Where(p => request.DateCreated == null || p.DateCreated.Date.CompareTo(((DateTime)request.DateCreated).Date) == 0)
                                     .Skip(request.Offset)
                                     .Take(request.Limit)
                                     .ToList()
                };
            });
        }
    }
}
